package com.create.myworld.sse;

import org.springframework.core.task.TaskExecutor;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/***
 * @author zcw
 * 长连接基类
 */
@RestController
@CrossOrigin
public abstract class SSE {

    @Resource
    private TaskExecutor taskExecutor;

    protected static final String normalKey = "normal";

    protected static final String dieKey = "die";

    protected static Map<String, SseEmitter> sseEmitterMap = new ConcurrentHashMap();

    /**
     * 建立长连接
     * @param request
     * @param type
     * @return
     */
    @RequestMapping(value = "/open", produces = {MediaType.TEXT_EVENT_STREAM_VALUE})
    public final SseEmitter open(HttpServletRequest request, String type) {
        String ip = getIPAddress(request) + type;
        SseEmitter sseEmitter = new SseEmitter(3600000L);
        sseEmitter.onCompletion(() -> {
            sseEmitterMap.remove(ip);
        });
        sseEmitterMap.put(ip, sseEmitter);
        taskExecutor.execute(() -> {
            push(null);
        });
        return sseEmitter;
    }

    public abstract void push(String content);

    /**
     * 获取ip地址
     *
     * @param request
     * @return
     */
    private String getIPAddress(HttpServletRequest request) {
        String ip = null;
        String ipAddresses = request.getHeader("X-Forwarded-For");
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            ipAddresses = request.getHeader("X-Real-IP");
        }
        if (ipAddresses != null && ipAddresses.length() != 0) {
            ip = ipAddresses.split(",")[0];
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}